#pragma once
#include "ContentControl.h"

namespace GUIToolkit
{
	class ButtonBase :
		public ContentControl
	{
	private:
		bool ispressed;
		PointF p;

	protected:
		virtual void OnMouseEvent(MouseEventArgs* e);
		virtual void OnKeyEvent(KeyEventArgs* e);

		virtual void OnClick()
		{
			this->Click(NULL);
		}

		bool IsPressed() const { return this->ispressed; }

	public:
		event Click;

		ButtonBase(float x, float y, float width, float height, LPWSTR text = NULL);
		virtual bool Focusable() const { return true; }
		~ButtonBase(void);
	};

	class Button :
		public ButtonBase
	{
	protected:
		virtual void OnPaintBackground(Graphics* g);
		virtual void OnPaintForeground(Graphics* g);

	public:
		Button(float x, float y, float width, float height, LPWSTR text = NULL);
		~Button(void);
	};

	#define UI_CHECK (PROPERTY::UI_USER+1)

	class CheckBox :
		public ButtonBase
	{
	private:
		bool ischecked;

	protected:
		virtual float OnPaintHeader(Graphics* g);
		virtual void OnPaintForeground(Graphics* g);

		virtual void OnClick()
		{
			this->SetChecked(!this->IsChecked());
			ButtonBase::OnClick();
		}

	public:
		CheckBox(float x, float y, float width, float height, LPWSTR text = NULL);

		bool IsChecked() const { return this->ischecked; }
		void SetChecked(bool value)
		{
			if(this->ischecked != value)
			{
				OnPropertyChanging((PROPERTY)UI_CHECK);
				this->ischecked = value;
				OnPropertyChanged((PROPERTY)UI_CHECK);
			}
		}

		~CheckBox(void);
	};

	class Option :
		public CheckBox
	{
	protected:
		virtual float OnPaintHeader(Graphics* g);

	public:
		Option(float x, float y, float width, float height, LPWSTR text = NULL);
		~Option(void);
	};

	#define UI_VALUE (PROPERTY::UI_USER+2)
	#define UI_RANGE (PROPERTY::UI_USER+3)

	class PrograssBar
		: public Control
	{
	private:
		int maxvalue;
		int minvalue;
		int value;

	protected:
		virtual void OnPaintBackground(Graphics* g);
		virtual void OnPaintForeground(Graphics* g);

	public:
		PrograssBar(float x, float y, float width, float height, LPWSTR text = NULL);

		bool SetRange(int min, int max)
		{
			if(this->maxvalue != max && this->minvalue != min)
			{
				if(max <= min) return false;
				OnPropertyChanging((PROPERTY)UI_RANGE);
				this->minvalue = min;
				this->maxvalue = max;
				OnPropertyChanged((PROPERTY)UI_RANGE);
			}
		}

		void GetRange(int &min, int &max) const
		{
			min = this->minvalue;
			max = this->maxvalue;
		}

		void SetValue(int value)
		{
			if( value < minvalue ) value = minvalue;
			if( value > maxvalue ) value = maxvalue;
			if(this->value != value)
			{
				OnPropertyChanging((PROPERTY)UI_VALUE);
				this->value = value;
				OnPropertyChanged((PROPERTY)UI_VALUE);
			}
		}

		int GetValue() const
		{
			return this->value;
		}

		~PrograssBar(void);
	};

	class TrackBar
		: public PrograssBar
	{
	protected:
		virtual void OnPaintBackground(Graphics* g);
		virtual void OnPaintForeground(Graphics* g);
		virtual void OnMouseEvent(MouseEventArgs* e);

	public:
		TrackBar(float x, float y, float width, float height, LPWSTR text = NULL);

		virtual bool Focusable() const { return true; }

		~TrackBar(void);
	};

	class ScrollBar
		: public Control
	{
	private:
		float value;

	protected:
		virtual void OnPaintBackground(Graphics* g);
		virtual void OnPaintForeground(Graphics* g);

	public:
		ScrollBar(float x, float y, float width, float height, LPWSTR text = NULL);

		void SetValue(float value)
		{
			if( value < 0.0f ) value = 0.0f;
			if( value > 1.0f ) value = 1.0f;
			if(this->value != value)
			{
				OnPropertyChanging((PROPERTY)UI_VALUE);
				this->value = value;
				OnPropertyChanged((PROPERTY)UI_VALUE);
			}
		}

		float GetValue() const
		{
			return this->value;
		}

		~ScrollBar(void);
	};

	#define UI_IMAGE (PROPERTY::UI_USER+4)
	#define UI_STRETCH (PROPERTY::UI_USER+5)

	class PictureBox
		: public UIElement
	{
	private:
		wstring url;
		Image* image;
		Stretch stretch;

	protected:
		virtual void OnPaint(Graphics* g);

	public:
		PictureBox(float x, float y, float width, float height, LPWSTR text = NULL);

		Image* GetImage() const;
		void SetImage(Image* img);
		void SetImage(wstring url);

		Stretch GetStretch() const;
		void SetStretch(Stretch s);

		~PictureBox(void);
	};

}